package cn.agiledata.bank.linkbank.impl.abc;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.hitrust.trustpay.client.TrxResponse;
import com.hitrust.trustpay.client.b2c.Order;
import com.hitrust.trustpay.client.b2c.PaymentRequest;
import cn.agiledata.bank.common.util.DateUtil;
import cn.agiledata.bank.linkbank.exception.LinkBankException;
import cn.agiledata.bank.linkbank.logic.payment.BankNetPayRequest;
import cn.agiledata.bank.linkbank.logic.payment.BankPayRequest;

/**
 * 中国农业银行网上银行支付请求
 * 
 * @author 马贤波
 * 
 */
public final class AbcNetPayRequest implements BankNetPayRequest {
    private String bankUrl;

    private PaymentRequest paymentRequest;

    private boolean valid;

    private boolean supported;

    public AbcNetPayRequest() {
        this.paymentRequest = new PaymentRequest();
        this.paymentRequest.setOrder(new Order());
        this.valid = true;
        this.supported = true;
        init();
    }

    private void init() {
        this.paymentRequest.setProductType(PaymentRequest.PRD_TYPE_ONE); // 非实体商品交易
        this.paymentRequest.setNotifyType(PaymentRequest.NOTIFY_TYPE_URL); // 页面通知方式
        this.paymentRequest.setPaymentType(PaymentRequest.PAY_TYPE_ABC); // 农行卡支付
        this.paymentRequest
                .setPaymentLinkType(PaymentRequest.PAY_LINK_TYPE_NET); // Internet网络接入
    }

    private Order getOrder() {
        return this.paymentRequest.getOrder();
    }

    public String getBankUrl() {
        return this.bankUrl;
    }

    public String getMerchantUrl() {
        return this.paymentRequest.getResultNotifyURL();
    }

    public void setMerchantUrl(String merchantUrl) {
        this.paymentRequest.setResultNotifyURL(merchantUrl);
    }

    public void setAmount(BigDecimal amount) {
        getOrder().setOrderAmount(amount.doubleValue());
    }

    public void setDate(Date date) {
        String dateValue = DateUtil.date2String(date,
                AbcNetConstant.DATE_FORMAT);
        getOrder().setOrderDate(dateValue);
        String timeValue = DateUtil.date2String(date,
                AbcNetConstant.TIME_FORMAT);
        getOrder().setOrderTime(timeValue);
    }

    public void setOrderId(String orderId) {
        getOrder().setOrderNo(orderId);
    }

    public void setOrderUrl(String orderUrl) {
        getOrder().setOrderURL(orderUrl);
    }

    public void setRemark(String remark) {
        getOrder().setOrderDesc(remark == null ? "" : remark);
    }

    public boolean isValid() {
        return this.valid;
    }

    public boolean isSupported() {
        return this.supported;
    }

    public String getSubmitMethod() {
        return SUBMIT_METHOD_POST;
    }

    public void prepare() throws LinkBankException {
        TrxResponse response = this.paymentRequest.postRequest();
        if (response.isSuccess()) {
            this.bankUrl = response.getValue(AbcNetConstant.PAYMENT_URL);
        } else {
            this.valid = false;
            String errorMessage = response.getErrorMessage();
            throw new LinkBankException(AbcNetConstant.EXCEPTION_UNIFORM_CODE,
                    errorMessage);
        }
    }

    public void setBankUrl(String bankUrl) {
    }

    public void setMerchantAccount(String merchantAccount) {
    }

    public void setCurrencyType(String currencyType) {
    }

    public void setParameter(String name, String value) {
    }

    public Map getParameters() {
        return new HashMap();
    }

    public BankPayRequest copy() {
        AbcNetPayRequest request = new AbcNetPayRequest();
        request.setBankUrl(getBankUrl());
        request.valid = this.valid;
        request.setMerchantUrl(getMerchantUrl());
        if (getOrder() != null) {
            request.getOrder().setOrderAmount(getOrder().getOrderAmount());
            request.getOrder().setOrderDate(getOrder().getOrderDate());
            request.getOrder().setOrderTime(getOrder().getOrderTime());
            request.getOrder().setOrderNo(getOrder().getOrderNo());
            request.getOrder().setOrderDesc(getOrder().getOrderDesc());
        }
        return request;
    }

}
